package com.ym.medical.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.hutool.crypto.digest.MD5;
import com.ym.core.config.ConfigCenterProperties;
import com.ym.core.utils.tkmybatis.BaseSVImpl;
import com.ym.core.utils.tkmybatis.TK;
import com.ym.medical.dao.SysSignDao;
import com.ym.medical.domain.entity.SysSignEntity;
import com.ym.medical.domain.param.SysSignQueryParam;
import com.ym.medical.domain.param.SysSignUpdateParam;
import com.ym.medical.domain.vo.SysSignListPcVO;
import com.ym.medical.enums.OrgEnum;
import com.ym.medical.enums.OrgSignEnum;
import com.ym.medical.service.ISysSignSV;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.KeyPair;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 系统签名表Service业务层处理
 *
 * @author ym
 * @date 2020-08-17
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysSignSVImpl extends BaseSVImpl<SysSignEntity, SysSignDao> implements ISysSignSV {

	/**
	 * 查询系统签名表列表
	 *
	 * @param queryParam 系统签名表 查询参数
	 * @return 系统签名表
	 */
	@Override
	public List<SysSignListPcVO> selectListPC(SysSignQueryParam queryParam) {
		List<SysSignListPcVO> sysSigns = mapper.selectListPC(queryParam);
		return sysSigns;
	}

	/**
	 * 新增系统签名表
	 *
	 * @param updateParam 系统签名表 新增参数
	 * @return 结果
	 */
	@Override
	public Long insertPC(SysSignUpdateParam updateParam) {
		SysSignEntity entity = updateParam.covert();
		this.insert(entity);
		return entity.getId();
	}

	/**
	 * 修改系统签名表
	 *
	 * @param updateParam 系统签名表 修改参数
	 * @return 结果
	 */
	@Override
	public int updateByIdPC(SysSignUpdateParam updateParam) {
		SysSignEntity entity = updateParam.covert("createTime");
		int result = this.updateById(entity);
		return result;
	}

	@Override
	public SysSignEntity createSign(OrgSignEnum orgEnum) {
		SysSignEntity sign = new SysSignEntity();
		KeyPair keyPair = KeyUtil.generateKeyPair(SignAlgorithm.MD5withRSA.getValue(), 512, null);
		String appSecret = Base64.encode(keyPair.getPrivate().getEncoded());
		String appKey = Base64.encode(keyPair.getPublic().getEncoded());
		sign.setAppKey(appKey);
		sign.setAppSecret(appSecret);
		sign.setOrgCode(orgEnum.getCode());
		sign.setOrgName(orgEnum.getName());
		this.insert(sign);
		return sign;
	}

	@Autowired
	private ConfigCenterProperties configCenterProperties;

	/**
	 * 获取交易签名头信息
	 *
	 * @param reqBody
	 * @return
	 */
	@Override
	public Map<String, String> getTdSignHeaders(String reqBody) {
		String appKey = configCenterProperties.getPayPlatform().getAppKey();
		Map<String, String> headers = new HashMap<>();
		long now = System.currentTimeMillis();
		headers.put("appKey", appKey);
		headers.put("timestamp", String.valueOf(now));
		//获取支付平台秘钥
		List<SysSignListPcVO> sysSignListPcVOS = selectListPC(SysSignQueryParam
				.builder()
				.appKey(appKey)
				.build());
		if (!sysSignListPcVOS.isEmpty()) {
			SysSignListPcVO sysSign = sysSignListPcVOS.get(0);
			String sign = MD5.create().digestHex(reqBody + "" + sysSign.getAppSecret() + "ym" + now);
			headers.put("sign", sign);
		}
		return headers;
	}

	@Override
	public SysSignEntity findSysSignByAppKey(String appKey) {
		return mapper.selectOneByExample(TK.select(SysSignEntity.class).where().andEqualTo(SysSignEntity::getAppKey, appKey));
	}
	@Override
	public SysSignEntity createSignByUser(OrgEnum orgEnum, Long userId) {
		SysSignEntity sign = new SysSignEntity();
		KeyPair rsa = KeyUtil.generateKeyPair(AsymmetricAlgorithm.RSA.getValue(), 512, userId.toString().getBytes());
		String appKey = java.util.Base64.getEncoder().encodeToString(rsa.getPublic().getEncoded());
		String appSecret = java.util.Base64.getEncoder().encodeToString(rsa.getPrivate().getEncoded());
		sign.setAppKey(appKey);
		sign.setAppSecret(appSecret);
		sign.setCreator(userId);
		sign.setOrgCode(orgEnum.getKey());
		sign.setOrgName(orgEnum.getValue());
		mapper.insertSelective(sign);
		return sign;
	}
}
